﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Diagnostics;
using System.Net.Sockets;
using EkspSys.Network;

namespace EkspSys.Map
{
    public delegate void UpdateHandler();

    public class EndPointInfo
    {
        private IPAddress address;
        
        public event UpdateHandler Updated;

        // Map: Port -> ProcessInfo
        private Dictionary<ushort, ProcessInfo> processes = new Dictionary<ushort, ProcessInfo>();

        public EndPointInfo(IPAddress address)
        {
            this.address = address;
            this.Location = GeoLookup.Get().LookupIPLocation(address);
        }

        public Location Location;

        public IPAddress Address
        {
            get
            {
                return address;
            }
        }

        public ProcessInfo GetProcessInfo(ushort port)
        {
            if (processes.ContainsKey(port))
                return processes[port];
            return null;
        }

        public void SetProcessInfo(ushort port, ProcessInfo info)
        {
            info.Updated += new UpdateHandler(delegate() {
                CallUpdateEvent();
            });

            processes[port] = info;
            CallUpdateEvent();
        }

        public List<KeyValuePair<ushort, ProcessInfo>> GetProcessInfoList()
        {
            return processes.ToList();
        }
        
        public override string ToString()
        {
            return address.ToString();
        }

        private void CallUpdateEvent()
        {
            if (Updated != null)
                Updated();
        }
    }

    public class ProcessInfo
    {
        public event UpdateHandler Updated;

        public Process Process;
        public Protocol Protocol;

        private ulong packets;
        private ulong data;

        // Number of packages send
        public ulong Packets
        {
            get
            {
                return packets;
            }
            set
            {
                CallUpdateEvent();
                packets = value;
            }
        }

        // Amount of data in bytes transfered
        public ulong Data
        {
            get
            {
                return data;
            }
            set
            {
                CallUpdateEvent();
                data = value;
            }
        }

        private void CallUpdateEvent()
        {
            if (Updated != null)
                Updated();
        }
    }
}
